<template>
  <!-- 电价时段管理 -->
  <div class="filterContent">
    <a-form :model="filterForm" layout="inline">
      <a-form-item label="省份">
        <a-select
          ref="select"
          v-model:value="filterForm.provId"
          class="formInput"
          placeholder="省份"
          show-search
          optionFilterProp="label"
          @change="changeProv"
        >
          <a-select-option
            v-for="item in provList"
            :key="item.provId"
            :value="item.provId"
            :label="item.provName"
          >
            {{ item.provName }}
          </a-select-option>
        </a-select>
      </a-form-item>
      <a-form-item label="规则执行时间">
        <a-range-picker
          v-model:value="filterForm.date"
          value-format="YYYY-MM"
          format="YYYY-MM"
          picker="month"
          :allowClear="false"
          separator="~"
        />
      </a-form-item>
      <a-button type="primary" class="filterBtn" @click="getElecRule"
        >查询</a-button
      >
      <a-button type="primary" class="yellowBtn" @click="handleEleChart"
        >电价快搜</a-button
      >
    </a-form>
  </div>
  <div class="priceContent">
    <div class="ruleContent">
      <div class="title">
        电价时段规则<a-button v-hasPermission="'elecPriceRuleAdd'" class="addRule" @click="handleAddRule"
          >新增规则</a-button
        >
      </div>
      <div class="ruleList">
        <a-spin :spinning="loading">
          <div class="rule" v-for="(item, index) in ruleList" :key="index">
            <div :class="['ruleType', colorBlock[index % 4]]" />
            <MoreOutlined class="moreBtn" @click="handleInfo(item, index)" />
            <div class="ruleName">{{ item.name }}</div>
            <div class="ruleDate">
              <span class="dateLabel">执行时间：</span
              ><span class="dateValue"
                ><span
                  v-for="(timeItem, timeIndex) in item.startEndTimes"
                  :key="timeIndex"
                  >{{ timeItem.startTime }}~{{ timeItem.endTime
                  }}<span
                    v-if="
                      timeIndex % 2 == 0 &&
                      timeIndex != item.startEndTimes.length - 1
                    "
                    >、</span
                  ></span
                ></span
              >
            </div>
          </div>
        </a-spin>
        <a-empty
          v-if="!ruleList.length"
          style="opacity: 0.5; margin-top: 50px"
        />
      </div>
    </div>
    <div class="dateContent">
      <div class="title">电价时段规则日历</div>
      <div class="calendar">
        <a-button
          class="today"
          @click="handleToday"
          :style="`right:${calendarMode === 'year' ? '208' : '285'}px`"
          >今天</a-button
        >
        <a-calendar
          v-model:value="today"
          :mode="calendarMode"
          @panelChange="panelChange"
        >
          <template #monthCellRender="{ current }">
            <div
              v-for="item in getMonthData(current)"
              :key="item.content"
              @click="handleDateInfo(item, index)"
            >
              <div class="colorContent">
                <div
                  :class="['colorBlock', item.type]"
                  :style="{ position: 'relative' }"
                />
                <div
                  :class="['colorText', `${item.type}Text`]"
                  :title="item.content"
                >
                  {{ item.content }}
                </div>
              </div>
            </div>
          </template>
          <template #dateCellRender="{ current }">
            <div
              v-for="(item, index) in getDateData(current)"
              :key="item.content"
              @click="handleDateInfo(item, index)"
            >
              <!-- :style="{top: (item.index) * 35 + 'px'}" -->
              <div class="colorContent">
                <div :class="['colorBlock', item.type]" />
                <div
                  :class="['colorText', `${item.type}Text`]"
                  :title="item.content"
                >
                  {{ item.content }}
                </div>
              </div>
            </div>
          </template>
        </a-calendar>
      </div>
    </div>
  </div>
  <!-- 规则表单 -->
  <AddRule
    :addRuleVisible="addRuleVisible"
    :provList="provList"
    :isAdd="isAdd"
    :isInfo="isInfo"
    :isEdit="isEdit"
    :rowData="rowData"
    @update:isAdd="(val) => (isAdd = val)"
    @update:isEdit="(val) => (isEdit = val)"
    @update:isInfo="(val) => (isInfo = val)"
    @update:addRuleVisible="(val) => (addRuleVisible = val)"
    @getElecRule="getElecRule"
  />
  <!-- 电价快搜 -->
  <EleChart
    :eleChartVisible="eleChartVisible"
    :provList="provList"
    @getElecRule="getElecRule"
    @update:eleChartVisible="(val) => (eleChartVisible = val)"
  />
</template>
<script setup>

import AddRule from "./components/addRule.vue";
import EleChart from "./components/eleChart.vue";
import dayjs from "dayjs";

import { color } from "echarts";
const $api = inject("$api");
const addRuleVisible = ref(false);
const eleChartVisible = ref(false);
const filterForm = ref({
  provId: 440000,
  date: null,
});

const colorBlock = {
  0: "jian",
  1: "feng",
  2: "ping",
  3: "gu",
  4: "shenGu",
};
const today = ref(dayjs());
// 时间范围映射
const timeRangeMappings = [
  { key: "superPeakTimeRange", type: "jian" },
  { key: "peakTimeRange", type: "feng" },
  { key: "flatTimeRange", type: "ping" },
  { key: "valleyTimeRange", type: "gu" },
  { key: "deepValleyTimeRange", type: "shenGu" },
];
const uniqueByField = (array, key) => {
  return [...new Map(array.map((item) => [item[key], item])).values()];
};
const getMonthData = (value) => {
  const year = value.year();
  const month = value.month();
  const targetDate = dayjs(new Date(year, month)).format("YYYY-MM");
  let results = [];
  // 遍历数据中的 startEndTimes
  ruleList.value.forEach((item, index) => {
    item.startEndTimes.forEach((timeRange) => {
      const startTime = dayjs(timeRange.startTime).format("YYYY-MM");
      const endTime = dayjs(timeRange.endTime).format("YYYY-MM");
      // 检查目标日期是否在时间范围内
      if (
        dayjs(targetDate).isSame(startTime) ||
        dayjs(targetDate).isSame(endTime) ||
        (dayjs(targetDate).isAfter(startTime, "day") &&
          dayjs(targetDate).isBefore(endTime))
      ) {
        results.push({
          item,
          type: colorBlock[index % 4],
          content: dayjs(targetDate).isSame(startTime) ? item.name : "", // 获取匹配到的 name
          index,
        });
      }
    });
  });
  return uniqueByField(results, "content"); // 可能同个月份会有相同的规则，需要根据content去重
};
const getDateData = (value) => {
  const year = value.year();
  const month = value.month();
  const date = value.date();
  const targetDate = dayjs(new Date(year, month, date)).format("YYYY-MM-DD");
  let results = [];
  // 遍历数据中的 startEndTimes

  ruleList.value.forEach((item, index) => {
    item.startEndTimes.forEach((timeRange, timeIndex) => {
      const startTime = dayjs(timeRange.startTime).format("YYYY-MM-DD");
      const endTime = dayjs(timeRange.endTime).format("YYYY-MM-DD");
      // 检查目标日期是否在时间范围内
      if (
        dayjs(targetDate).isSame(startTime) ||
        dayjs(targetDate).isSame(endTime) ||
        (dayjs(targetDate).isAfter(startTime, "day") &&
          dayjs(targetDate).isBefore(endTime))
      ) {
        results.push({
          item,
          type: colorBlock[index % 4],
          content: dayjs(targetDate).isSame(startTime) ? item.name : "", // 获取匹配到的 name
          index,
        });
      }
    });
  });
  return results;
};
const handleAddRule = () => {
  isAdd.value = true;
  isEdit.value = false;
  isInfo.value = false;
  addRuleVisible.value = true;
};
const handleToday = () => {
  today.value = dayjs();
};
const handleEleChart = () => {
  eleChartVisible.value = true;
};
const provList = ref([]);
const getProvList = async () => {
  const res = await $api.elecRuleProvinces();
  provList.value = res?.data;
};
const ruleList = ref([]);
const loading = ref(false);
const getElecRule = async () => {
  const params = {
    provId: filterForm.value.provId,
    startDate: filterForm.value.date?.[0]
      ? filterForm.value.date[0] + "-01"
      : "",
    endDate: filterForm.value.date?.[1] ? filterForm.value.date[1] + "-01" : "",
  };
  loading.value = true;
  const res = await $api.getElecRule(params);
  loading.value = false;
  if (res && res.code === 0) {
    ruleList.value = res.data;
  }
};
const isAdd = ref(false);
const isInfo = ref(false);
const isEdit = ref(false);
const rowData = ref({});
const handleInfo = (item, index) => {
  rowData.value = item;
  isInfo.value = true;
  isAdd.value = false;
  isEdit.value = false;
  addRuleVisible.value = true;
};
const handleDateInfo = (item, index) => {
  rowData.value = item.item;
  isInfo.value = true;
  isAdd.value = false;
  isEdit.value = false;
  addRuleVisible.value = true;
};
const calendarMode = ref("year");
const panelChange = (date, mode) => {
  calendarMode.value = mode;
};
onMounted(async () => {
  await getProvList();
  await getElecRule();
});
</script>

<style lang="less" scoped>
.formInput {
  width: 155px;
}
.priceContent {
  display: table;
}

.ruleContent,
.dateContent {
  border-radius: 4px;
  background-color: #141414;
  border: 1px solid #666;
  border-radius: 4px;
  .title {
    height: 50px;
    line-height: 50px;
    border-bottom: 1px solid #666;
    font-size: 14px;
    padding: 0 20px;
    position: relative;
  }
  .addRule {
    position: absolute;
    right: 20px;
    top: 10px;
  }
}
.ruleContent {
  width: 450px;
  margin-right: 20px;
  height: 816px;
}
.dateContent {
  width: calc(100% - 20px);
  vertical-align: top;

  display: table-cell;
}
.ruleList {
  padding: 20px 15px;
  height: 750px;
  overflow-y: scroll;
}
.rule {
  border: 1px solid #666;
  border-radius: 4px;
  padding: 10px 20px 10px 20px;
  margin-bottom: 20px;
  position: relative;
  &:last-child {
    margin-bottom: 0;
  }
  .ruleType {
    width: 3px;
    height: calc(100% - 20px);
    left: 9px;
    position: absolute;
  }
  .ruleName {
    font-size: 14px;
    margin-bottom: 10px;
  }
  .ruleDate {
    font-size: 12px;
  }
  .dateLabel {
    display: inline-block;
    width: 60px;
    position: relative;
    top: 2px;
  }
  .dateValue {
    display: inline-block;
    width: calc(100% - 60px);
    vertical-align: text-top;
    line-height: 1.5;
  }
  .moreBtn {
    position: absolute;
    right: 0;
    font-size: 30px;
    font-weight: bold;
    top: 50%;
    transform: translate(0, -50%);
    cursor: pointer;
  }
}
@jian: #ec7f8c;
@feng: #f59a23;
@ping: #ffff80;
@gu: #96f203;
@shenGu: #81d3f8;
.jian {
  background: @jian;
}
.jianText {
  color: @jian;
}
.feng {
  background: @feng;
}
.fengText {
  color: @feng;
}
.ping {
  background: @ping;
}
.pingText {
  color: @ping;
}
.gu {
  background: @gu;
}
.guText {
  color: @gu;
}
.shenGu {
  background: @shenGu;
}
.shenGuText {
  color: @shenGu;
}
.colorItem {
  margin-top: 5px;
}
.colorContent {
  position: relative;
}
.colorText {
  position: absolute;
  top: 0;
  left: 10px;
  height: 30px;
  line-height: 30px;
  width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.colorBlock {
  width: 100%;
  height: 30px;
  line-height: 30px;
  opacity: 0.4;
  position: absolute;
}
::v-deep(.ant-picker-calendar-date) {
  padding: 0 !important;
  margin: 0 !important;
}
::v-deep(.ant-picker-calendar-date-value) {
  padding: 0 10px;
}
::v-deep(.ant-picker-calendar-date-content) {
  overflow-x: hidden;
}
.calendar {
  padding: 0 10px;
  position: relative;
}
.today {
  position: absolute;
  top: 12px;
}
.filterBtn {
  margin-right: 20px;
}
</style>
